<template>
  <div class="canvas-map">
    <canvas
      id="canvas-map"
      ref="canvasRef"
      @mousedown="handleMouseDown"
      @mousemove="handleMouseMove"
      @mouseup="handleMouseUp"
      @mouseleave="handleMouseLeave"
    ></canvas>
    <div class="control-buttons">
      <div class="zoom-controls">
        <button @click="handleZoom('in')">+</button>
        <button @click="handleZoom('out')">-</button>
      </div>
      <div class="draw-controls">
        <template v-if="!isDrawing">
          <button @click="startDrawing">绘制</button>
        </template>
        <template v-else>
          <button @click="confirmDrawing">确认</button>
          <button @click="cancelDrawing">取消</button>
        </template>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, onBeforeUnmount } from 'vue'

const props = defineProps({
  mapUrl: {
    type: String,
    required: true,
  },
  points: {
    type: Array,
    default: () => [{ x: 5355, y: 2723, width: 127, height: 54 }],
  },
})

const emits = defineEmits(['draw-complete'])
const canvasRef = ref(null)
const scale = ref(1)
const minScale = 0.1 // 修改最小缩放比例
const maxScale = 2
let ctx = null
const imgRef = ref(null)

// 添加拖动相关状态
const isDragging = ref(false)
const dragStart = ref({ x: 0, y: 0 })
const offset = ref({ x: 0, y: 0 })

const isDrawing = ref(false)
const drawStart = ref(null)
const drawEnd = ref(null)
const tempRect = ref(null)

const initCanvas = () => {
  const canvas = canvasRef.value
  ctx = canvas.getContext('2d')
  canvas.width = canvas.parentElement.clientWidth
  canvas.height = canvas.parentElement.clientHeight

  imgRef.value = new Image()
  imgRef.value.src = props.mapUrl
  imgRef.value.onload = () => drawImage()
}

const startDrag = (e) => {
  isDragging.value = true
  dragStart.value = {
    x: e.clientX - offset.value.x,
    y: e.clientY - offset.value.y,
  }
}

const onDrag = (e) => {
  if (!isDragging.value) return
  offset.value = {
    x: e.clientX - dragStart.value.x,
    y: e.clientY - dragStart.value.y,
  }
  drawImage()
}

const stopDrag = () => {
  isDragging.value = false
}

const handleMouseDown = (e) => {
  if (isDrawing.value) {
    const rect = canvasRef.value.getBoundingClientRect()
    // 计算鼠标相对于图片的实际位置
    const mouseX = e.clientX - rect.left
    const mouseY = e.clientY - rect.top

    // 获取图片在Canvas中的实际位置和大小
    const imagePos = getImagePosition()

    // 将鼠标位置转换为相对于图片的坐标
    drawStart.value = {
      x: (mouseX - imagePos.x) / scale.value,
      y: (mouseY - imagePos.y) / scale.value,
    }

    tempRect.value = null
  } else {
    startDrag(e)
  }
}

const handleMouseMove = (e) => {
  if (isDrawing.value && drawStart.value) {
    const rect = canvasRef.value.getBoundingClientRect()
    const mouseX = e.clientX - rect.left
    const mouseY = e.clientY - rect.top

    const imagePos = getImagePosition()

    drawEnd.value = {
      x: (mouseX - imagePos.x) / scale.value,
      y: (mouseY - imagePos.y) / scale.value,
    }

    // 立即更新临时矩形
    if (drawStart.value && drawEnd.value) {
      tempRect.value = calculateRect(drawStart.value, drawEnd.value)
    }

    drawImage()
  } else {
    onDrag(e)
  }
}

const handleMouseUp = (e) => {
  if (isDrawing.value) {
    if (drawStart.value && drawEnd.value) {
      tempRect.value = calculateRect(drawStart.value, drawEnd.value)
      drawStart.value = null
      drawEnd.value = null
      drawImage()
    }
  } else {
    stopDrag()
  }
}

const handleMouseLeave = () => {
  if (!isDrawing.value) {
    stopDrag()
  }
}

const calculateRect = (start, end) => {
  const x = Math.min(start.x, end.x)
  const y = Math.min(start.y, end.y)
  const width = Math.abs(end.x - start.x)
  const height = Math.abs(end.y - start.y)
  return { x, y, width, height }
}

// 新增：获取图片在Canvas中的实际位置
const getImagePosition = () => {
  const centerX = (ctx.canvas.width - imgRef.value.width * scale.value) / 2 + offset.value.x
  const centerY = (ctx.canvas.height - imgRef.value.height * scale.value) / 2 + offset.value.y

  return {
    x: centerX,
    y: centerY,
    width: imgRef.value.width * scale.value,
    height: imgRef.value.height * scale.value,
  }
}

// 修改绘制临时矩形的方法
const drawTempRect = () => {
  if (!tempRect.value) return

  ctx.save()
  const imagePos = getImagePosition()

  ctx.translate(imagePos.x, imagePos.y)
  ctx.scale(scale.value, scale.value)

  // 绘制半透明填充
  ctx.fillStyle = 'rgba(0, 123, 255, 0.3)'
  ctx.fillRect(tempRect.value.x, tempRect.value.y, tempRect.value.width, tempRect.value.height)

  // 绘制边框
  ctx.strokeStyle = '#007bff'
  ctx.lineWidth = 1 / scale.value
  ctx.strokeRect(tempRect.value.x, tempRect.value.y, tempRect.value.width, tempRect.value.height)

  ctx.restore()
}

// 修改绘制方法
const drawImage = () => {
  if (!ctx || !imgRef.value) return

  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)

  const imagePos = getImagePosition()

  // 绘制背景图片
  ctx.save()
  ctx.translate(imagePos.x, imagePos.y)
  ctx.scale(scale.value, scale.value)
  ctx.drawImage(imgRef.value, 0, 0)
  ctx.restore()

  // 绘制已保存的点
  drawPoints()

  // 绘制当前正在绘制的矩形
  if (isDrawing.value && tempRect.value) {
    drawTempRect()
  }
}

const startDrawing = () => {
  isDrawing.value = true
  drawStart.value = null
  drawEnd.value = null
  tempRect.value = null
}

const confirmDrawing = () => {
  if (tempRect.value) {
    emits('draw-complete', tempRect.value)
  }
  isDrawing.value = false
  drawStart.value = null
  drawEnd.value = null
  tempRect.value = null
  drawImage()
}

const cancelDrawing = () => {
  isDrawing.value = false
  drawStart.value = null
  drawEnd.value = null
  tempRect.value = null
  drawImage()
}

const drawPoints = () => {
  if (!ctx || !props.points || props.points.length === 0) return
  props.points.forEach((point) => {
    ctx.save()
    const centerX = (ctx.canvas.width - imgRef.value.width * scale.value) / 2 + offset.value.x
    const centerY = (ctx.canvas.height - imgRef.value.height * scale.value) / 2 + offset.value.y

    ctx.translate(centerX, centerY)
    ctx.scale(scale.value, scale.value)

    // 绿色填充
    ctx.fillStyle = 'rgba(103, 194, 58, 0.3)' // #67C23A 带透明度
    ctx.fillRect(point.x, point.y, point.width, point.height)

    // 绿色边框
    ctx.strokeStyle = '#67C23A'
    ctx.lineWidth = 2 / scale.value
    ctx.strokeRect(point.x, point.y, point.width, point.height)
    ctx.restore()
  })
}

const handleZoom = (type) => {
  const delta = type === 'in' ? 0.1 : -0.1
  const newScale = scale.value + delta

  if (newScale >= minScale && newScale <= maxScale) {
    scale.value = newScale
    drawImage()
  }
}

watch(
  () => props.mapUrl,
  (newUrl) => {
    if (imgRef.value) {
      imgRef.value.src = newUrl
      imgRef.value.onload = () => {
        drawImage()
      }
    }
  }
)

// 添加对 points 的监听
watch(
  () => props.points,
  () => {
    drawImage()
  },
  { deep: true }
)

onMounted(() => {
  initCanvas()
  window.addEventListener('resize', initCanvas)
})

// 组件卸载时清理事件监听
onBeforeUnmount(() => {
  window.removeEventListener('resize', initCanvas)
})

// 添加跳转中心方法
const centerAt = (centerX, centerY) => {
  if (!ctx || !imgRef.value) return

  // 获取画布中心点
  const canvasCenterX = ctx.canvas.width / 2
  const canvasCenterY = ctx.canvas.height / 2

  // 获取图片在Canvas中的位置
  const imagePos = {
    x: (ctx.canvas.width - imgRef.value.width * scale.value) / 2,
    y: (ctx.canvas.height - imgRef.value.height * scale.value) / 2,
  }

  // 计算偏移量：
  // 画布中心点 - (图片初始位置 + 目标点的缩放坐标)
  offset.value = {
    x: canvasCenterX - (imagePos.x + centerX * scale.value),
    y: canvasCenterY - (imagePos.y + centerY * scale.value),
  }

  drawImage()
}

// 暴露方法给父组件
defineExpose({
  centerAt,
})
</script>

<style lang="scss" scoped>
.canvas-map {
  width: 100%;
  height: 100%;
  position: relative;

  canvas {
    width: 100%;
    height: 100%;
  }

  .control-buttons {
    position: absolute;
    right: 20px;
    bottom: 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;

    .draw-controls {
      display: flex;
      gap: 8px;
      margin-bottom: 8px;

      button {
        padding: 4px 8px;
        border: 1px solid #ddd;
        background: white;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;

        &:hover {
          background: #f5f5f5;
        }
      }
    }
  }

  .zoom-controls {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;

    button {
      width: 32px;
      height: 32px;
      border: 1px solid #ddd;
      background: white;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      display: flex;
      align-items: center;
      justify-content: center;

      &:hover {
        background: #f5f5f5;
      }
    }
  }
}
</style>
